const Router = require('express').Router
const express = require('express')
const multer = require('multer')
const { join } = require('path')
const { createReadStream } = require('fs')
const { sign, verify } = require('../util/token')
const GitService = require('../service/git.service')
const UserService = require('../service/user.service')
const { RepoItem } = require('../model/user')
const { RESOURCE_AVATAR, GIT_HTTP_PATH } = require('../contants')
const router = Router()
const upload = multer({
    storage: multer.diskStorage({
        destination(req, file, cb) {
            cb(null, RESOURCE_AVATAR)
        },
        filename(req, file, cb) {
            cb(null, `${req.query.username}.png`)
        }
    })
})

router.get('/config', async (req, res) => {
    res.send({
        code: 20000,
        data: {
            git_http_path: GIT_HTTP_PATH
        }
    })
})

router.get('/user', async (req, res) => {
    const { username } = req.query
    const userService = new UserService()
    const user = await userService.findOneByUsername(username)
    res.send({
        code: 20000,
        data: {
            user,
        }
    })
})

router.post('/user', express.json(), async(req, res) => {
    const { username, password } = req.body
    const gitService = new GitService()
    const userService = new UserService()
    const isExist = await userService.isExistByUserName(username)
    if (isExist) {
        return res.send({
            code: 20001,
            message: 'username is exist',
        })
    }
    await gitService.createUserRoot(username)
    const item = {
        username,
        password,
        info: {
            nickname: username,
            bio: '',
            address: '',
            link: '',
            twitter: '',
        },
        repos: [],
    }
    await userService.create(item);
    res.send({
        code: 20000,
        message: 'ok',
    })
})

router.post('/user/login', express.json(), async (req, res) => {
    const { username, password } = req.body
    if (username && password) {
        const userService = new UserService()
        const user = await userService.findOneByUsername(username)
        if (user) {
            if (user.password === password) {
                res.send({
                    code: 20000,
                    data: {
                        token: sign(username),
                    }
                })
            } else {
                res.send({
                    code: 20003
                })
            }
        } else {
            res.send({
                code: 20002
            })
        }
    } else {
        res.send({
            code: 20001,
        })
    }
})

router.get('/user/info', async (req, res) => {
    const { token } = req.query
    try {
        const { username, timestamp } = verify(token)
        const userService = new UserService()
        const user = await userService.findOneByUsername(username)
        if (user) {
            return res.send({
                code: 20000,
                data: {
                    username,
                    ...user.info
                }
            })
        }
        return res.send({
            code: 20002,
        })
    } catch(err) {
        res.send({
            code: 20001,
        })
    }
})

router.post('/user/repo', express.json(), async (req, res) => {
    const { username, name, type, comment } = req.body
    const updated_time = ''
    const relative_time = ''
    const is_overviews = false

    const userService = new UserService()
    const gitService = new GitService()
    const user = await userService.findOneByUsername(username)
    if (!user) {
        return res.send({
            code: 20001,
            message: 'user is not exist'
        })
    }
    const repoIndex = user.repos.findIndex(i => i.name === name)
    if (repoIndex !== -1) {
        return res.send({
            code: 20002,
            message: '该仓库已经存在'
        })
    }

    await userService.createRepoItemByUsername(username, new RepoItem(name, type, comment, updated_time, is_overviews, relative_time))
    await gitService.create(user.username, name)
    res.send({
        code: 20000,
        message: 'ok',
    })

}) 

router.put('/user/repo/overviews', express.json(), async (req, res) => {
    const overviews = req.body.overviews
    const username = req.body.username
    const userService = new UserService()
    
    const user = await userService.findOneByUsername(username)
    const repos = user.repos
    const reposMap = new Map()
    repos.forEach(repo => {
        reposMap.set(repo.name, repo)
    })
    Object.keys(overviews).forEach(key => {
        if (reposMap.has(key)) {
            const repo = reposMap.get(key)
            repo.is_overviews = overviews[key]
        }
    })
    await userService.create(user)
    
    res.send({
        code: 20000,
        message: 'ok',
    })
})
router.put('/user/profile', upload.single('avatar'), async (req, res) => {
    const username = req.query.username
    const { nickname, link, address, bio, twitter, school } = req.body
    const userService = new UserService()
    const user = await userService.findOneByUsername(username)
    const info = user.info
    Object.assign(info, {
        nickname,
        bio,
        link,
        address,
        twitter,
        school,
    })
    await userService.create(user)
    res.send({
        code: 20000,
    })
})

router.put('/user/repo/profile', express.json() ,async (req, res) => {
    const { username, repo, branch, description, website } = req.body
    const userService = new UserService()
    const user = await userService.findOneByUsername(username)
    const repoItem = user.repos.find(i => i.name === repo)
    if (repoItem) {
        const branchItem = repoItem.branch[branch]
        if (branchItem) {
            branchItem.profile = {
                description,
                website,
            }
            await userService.create(user)
            return res.send({
                code: 20000
            })
        }
    }
    return res.send({
        code: 20001,
    })
})

router.get('/user/info/avatar', (req, res) => {
    const stream = createReadStream(join(RESOURCE_AVATAR, `${req.query.username}.png`))
    res.setHeader('Content-Type', 'application/octet-stream')
    stream.pipe(res)
})

module.exports = router